#ifndef _game_Player_hpp_
#define _game_Player_hpp_

/** \file Player.hpp
 *  \author Adrian Schweizer
 *  \created  $Sa 18 Aug 03:48:01 pm CEST 2007 schwadri@SchwadriComp.local$
 *  \modified $So 30 Sep 04:48:23 pm CEST 2007 schwadri@SchwadriLaptop$
 */

#include <string>

#include <boost/serialization/access.hpp>

#include "../network/Types.hpp"
#include "../network/Client.hpp"

namespace game {

    //forward decl
    class Team;

    /** \brief A Player
     *
     *  Each Player belongs at most to one Client. A Client may own multiple players.
     *  A Player always belongs to a team or to the INVALID team.
     */
    class Player
    {
    public:
        //FIXME:typedef std::priority_queue<SyncFrame,std::vector<SyncFrame> >      sync_queue;

        /** \brief A unique Player identification
         *
         */
        struct Id
        {
            /** \brief default ctor
             *
             *  The playerid is set to INVALID
             */
            Id()
            :   team(-1),
                player(-1)
            { }

            /** \brief ctor
             *
             *  \param[in] t teamid of the team to which the player belongs
             *  \param[in] p the player index inside of the team
             */
            Id(char t, char p)
            :   team(t),
                player(p)
            { }

            static const Id     INVALID; ///< an invalid player id

            /** \brief check if the Id is valid
             *
             *  \return \a true if the team and the player index are valid
             */
            bool    Valid() const { return player!=-1 && team != -1; }

            char    team;   ///< teamid of the team to which the player belongs
            char    player; ///< player index inside of the team

            friend class boost::serialization::access;
        private:
            /** \brief serialize method for boost::archive compatible archives*/
            template<class Archive>
                void serialize(Archive & ar, const unsigned int version)
                {
                    ar & team;
                    ar & player;
                }
        };

        /** \brief default ctor
         *
         *  
         */
        Player()
        :   m_cid(network::Client::INVALID),
            m_ready(false)
        { }

        /** \brief construct a player from a clientid and a name*/
        Player(network::Client::Id cid, const std::string& name="")
        :   m_cid(cid),
            m_ready(false),
            m_name(name)
        { }

        /** \name Accessors */ //@{
        network::Client::Id ClientId() const                { return m_cid; }
        Id                  PlayerId() const                { return m_id; }
        char                PlayerIndex() const             { return m_id.player; }
        char                TeamId() const                  { return m_id.team; }
        bool                Ready() const                   { return m_ready; }
        const std::string&  Name() const                    { return m_name; }
        //@}

        /** \name Mutators */ //@{
        void                ClientId(network::Client::Id cid)   { m_cid = cid; }
        void                PlayerId(Id pid)                    { m_id = pid; }
        void                PlayerIndex(char pid)               { m_id.player = pid; }
        void                TeamId(char tid)                    { m_id.team = tid; }
        void                Ready(bool ready)                   { m_ready = ready; }
        void                Name(const std::string& name)       { m_name = name; }
        //@}

        friend class boost::serialization::access;
     private:
        /** \brief serialize method for boost::archive compatible archives*/
        template<class Archive>
            void serialize(Archive & ar, const unsigned int version)
            {
                ar & m_id;
                ar & m_cid;
                ar & m_ready;
                ar & m_name;
            }

        Id                  m_id;
        network::Client::Id m_cid;
        bool                m_ready;
        std::string         m_name;
        friend class Team;
    };

} // namespace game

#endif // _game_Player_hpp_
